package com.heima.tanhua.serivce.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.jwt.JWTUtil;

import com.heima.tanhua.dto.UserInfoDto;
import com.heima.tanhua.dto.userDto;
import com.heima.tanhua.pojo.Follow;
import com.heima.tanhua.pojo.User;
import com.heima.tanhua.mapper.UserMapper;
import com.heima.tanhua.serivce.UserService;
import com.heima.tanhua.thread.UserThreadLocal;
import com.heima.tanhua.vo.LikeVo;
import com.heima.tanhua.vo.LoginVo;
import com.heima.tanhua.vo.RecommendationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.heima.tanhua.constant.RedisConstant.GEO_KEY;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public boolean sendMsg(String phone) {
        int number = new Random().nextInt(100000) + 100000;
        log.info("验证码是：{}", number);
        redisTemplate.opsForValue().set("CODE" + phone, number + "", 5L, TimeUnit.HOURS);

        return true;
    }

    @Override
    public LoginVo login(userDto dto) {
        if (dto == null || StringUtils.isEmpty(dto.getPhone()) || StringUtils.isEmpty(dto.getCode())) {
            throw new RuntimeException("入参不能为空");
        }
        String code = dto.getCode();
        String phone = dto.getPhone();
        String codeFromRedis = redisTemplate.opsForValue().get("CODE" + phone);
        if (!code.equals(codeFromRedis)) {
            throw new RuntimeException("验证码校验失败");
        }
        User user = userMapper.selectByPhone(phone);
        if (user == null) {
            user = new User();
            String id = IdUtil.getSnowflakeNextIdStr();
            user.setId(id);
            user.setIsDelete(1);
            user.setCreateTime(LocalDateTime.now());
            user.setPhone(phone);
            user.setUpdateTime(LocalDateTime.now());
            user.setNickname("用户" + id);
            boolean insert = userMapper.insert(user);
            if (!insert) {
                throw new RuntimeException("创建用户失败");
            }
        }
        // 4.如果存在，生成token(工具类)-》JWT
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("phone", user.getPhone());
        String token = JWTUtil.createToken(map, "tanhua".getBytes());
        boolean firstLogin = false;

        Integer gender = user.getGender();
        String nickname = user.getNickname();
        String city = user.getCity();
        String birthday = user.getBirthday();
        if (gender == null || StringUtils.isEmpty(nickname) || StringUtils.isEmpty(city) || StringUtils.isEmpty(birthday)) {
            firstLogin = true;
        }
        LoginVo vo = new LoginVo();
        vo.setToken(token);
        vo.setFirstLogin(firstLogin);
        return vo;
    }

    @Override
    public boolean fillUserInfo(UserInfoDto dto) {
        // 1.判断入参
        if (dto == null || StringUtils.isEmpty(dto.getBirthday()) || StringUtils.isEmpty(dto.getGender())
                || StringUtils.isEmpty(dto.getCity()) || StringUtils.isEmpty(dto.getNickname())) {
            throw new RuntimeException("入参不能为空");
        }
        // 2. 通过ThreadLocal获得用户id
        String id = UserThreadLocal.get();
        // 3.执行update操作
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不能为空");
        }
        BeanUtils.copyProperties(dto, user);
        user.setUpdateTime(LocalDateTime.now());
        boolean res = userMapper.updateById(user);
        // 4.返回结过
        return res;
    }

    @Override
    public boolean updateUser(User user) {
        boolean res = userMapper.updateUserById(user);
        return res;
    }

    @Override
    public List<RecommendationVo> getRecommendationList(Double longitude, Double latitude,Integer page,Integer pageSize) {

        if (longitude == null || latitude == null) {
            throw new RuntimeException("入参不能为空");
        }
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                // 包含距离
                .includeDistance()
                // 包含经纬度
                .includeCoordinates()
                // 升序
                .sortAscending()
                // 最大查询数量
                .limit(1000);
        // radius
        Point point = new Point(longitude, latitude);
        // 半径
        Distance distance = new Distance(2, Metrics.KILOMETERS);
        // 画圆
        Circle circle = new Circle(point, distance);
        // 查询周边用户
        GeoResults<RedisGeoCommands.GeoLocation<String>> radius = redisTemplate.opsForGeo().radius(GEO_KEY, circle, args);
        System.out.println(radius);
        List<String> idList=new ArrayList<>();
        //3.从redis得到一个id集合（周边用户id）
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = radius.getContent();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> result : content) {
            RedisGeoCommands.GeoLocation<String> content1 = result.getContent();
            String name = content1.getName();
            System.out.println(name);
        }
        // 4.以id集合查询用户信息
        List<User> users = userMapper.selectByIds(idList,page,pageSize);
        //完成分页功能

        //5.年龄，缘分值要额外处理
        return null;
        
    }


    /**
     * 根据拿到的所有用户id 封装成followVo对象集合返回
     *
     * @param loveMeList
     * @return
     */
    private List<LikeVo> getFollowVos(List<Follow> loveMeList) {
        List<LikeVo> likeVos = new ArrayList<>();
        for (Follow follow : loveMeList) {

            String followId = follow.getFollowId();
            User user = userMapper.selectById(followId);
            LikeVo likeVo = new LikeVo();
            BeanUtils.copyProperties(user, likeVo);
            likeVo.setUserId(user.getId());
            likeVos.add(likeVo);
        }

        return likeVos;
    }
}
